<?php
defined('_JEXEC') or die('Restricted access');

jimport('joomla.application.component.controller');

function joomlaAutoloader($class) {
    if (JLoader::load($class)) {
        return true;
    }
    return false;
}

/**
 * A fix for joomla autoloader, joomla took the wrong desition of overriding
 * the __autoload function instead of registering one via the spl_autoload_register
 * function.
 */
spl_autoload_register("joomlaAutoloader");

/**
 * The underscore joomla front controller.
 *
 * @author Virtualidad
 */
class _Controller extends JController {

    private $view;
    /**
     *
     * @var ModuleStorage 
     */
    private $moduleStorage;

    public function __construct($config = array()) {
        parent::__construct($config);
        parent::registerDefaultTask("doTask");

        $document = &JFactory::getDocument();
        $this->view = &$this->getView('_', $document->getType());

        $this->moduleStorage = ModuleStorage::instance();
    }
    
    /**
     * Gets from the configuration manager the default module call which
     * will be used if there is any error in the module request or if it is
     * not specified at all.
     *  
     * @return ModuleCall The dafault module call.
     */
    public function getDefaultModuleCall(){
        $app = $this->getConfig()->get("DefaultApp");
        $module = $this->getConfig()->get("DefaultModule");
        $task = "index";
        
        return new ModuleCall($app, $module, $task);
    }
    
    /**
     * Retrieves from the configuration manager the module which shall manage any
     * unhandled exception.
     * 
     * @param UnderscoreException $ex
     * @return ModuleCall 
     */
    public function getErrorsModuleCall(UnderscoreException $ex){
        $app = $this->getConfig()->get("ErrorsApp");
        $module = $this->getConfig()->get("ErrorsModule");
        $task = "index";
        
        return new ModuleCall($app, $module, $task, $ex);
    }

    public function doTask() {

        $call = $this->getDefaultModuleCall();

        $controller = JRequest::getVar("controller", null);

        if (!empty($controller)) {
            
            $moduleRoute = explode(".", $controller);
            if ($this->moduleStorage->applicationExsists($moduleRoute[0])) {
                $call->setApp($moduleRoute[0]);
            }
            
            if (!empty ($moduleRoute[1])) {
                $call->setModule($moduleRoute[1]);
            }
        }

        $task = JRequest::getVar("task", "index");
        $call->setTask($task);

        $this->executeController($call);
    }

    /**
     *
     * @return AppConfig
     */
    private function getConfig() {
        return ModulesContext::instance()->getConfig();
    }

    public function executeController(ModuleCall $call) {
        
        try {
            $html = $this->moduleStorage->execute($call);
        } catch (UnderscoreException $ex) {
            $errorsCall = $this->getErrorsModuleCall($ex);
            $html = $this->moduleStorage->execute($errorsCall);
        }

        if (isset($html)) {
            $this->view->assignRef("html", $html);
            $this->view->display();
        }
    }

    public function execute($task) {
        $isAjax = JRequest::getVar("ajax", false);

        global $mainframe;
        $return = parent::execute($task);

        if ($isAjax) {
            $mainframe->close();
        }

        return $return;
    }

}

?>
